package com.lin.util;

import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Xml文件读取工具
 *
 * @author 九分石人, 2020-02-17
 */
@Slf4j
public class XmlParseUtil {

    /**
     * 根据节点获取节点的属性值
     *
     * @param node 要获取属性值的节点
     * @return 节点的属性值
     * @author com.lin, 2020-02-20
     */
    public static Map<String, String> getAttrByNode(Node node) {
        Map<String, String> attrMap = new HashMap<>(0);
        NamedNodeMap attributes = node.getAttributes();
        for (int j = 0; j < attributes.getLength(); j++) {
            Node attr = attributes.item(j);
            String nodeName = attr.getNodeName();
            String nodeValue = attr.getNodeValue();
            attrMap.put(nodeName, nodeValue);
        }
        return attrMap;
    }

    /**
     * 获取节点的子节点名和子节点值
     *
     * @param node 要获取子节点名和值的节点
     * @return 子节点的名和值
     * @author com.lin, 2020-02-20
     */
    public static Map<String, String> getChildNodeValueByNode(Node node) {
        Map<String, String> nodeMap = new HashMap<>(0);
        NodeList childNodes = node.getChildNodes();
        for (int j = 0; j < childNodes.getLength(); j++) {
            //排除掉换行造成的无效节点
            if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {
                String nodeName = childNodes.item(j).getNodeName();
                String nodeValue = childNodes.item(j).getFirstChild().getNodeValue();
                nodeMap.put(nodeName, nodeValue);
            }
        }
        return nodeMap;
    }


    /**     * 读取Xml文件，后续根据此方法进行修改，进行二次开发

     *
     * @param filepath Xml文件的路径
     * @param node     Xml文件中根结点的名称
     * @author com.lin, 2020-02-19
     */
    public static void ReadXml(String filepath, String node) {

        NodeList elementsByTagName = getNodeList(filepath, node);
        assert elementsByTagName != null;
        for (int i = 0; i < elementsByTagName.getLength(); i++) {
            Node item = elementsByTagName.item(i);
            //获取节点的所有属性
            Map<String, String> attrMap = XmlParseUtil.getAttrByNode(item);
            //获取节点所有子节点值
            Map<String, String> childNodeValueByNode = XmlParseUtil.getChildNodeValueByNode(item);
        }
    }

    /**
     * 读取Xml文件，获取根结点集合
     *
     * @param filepath Xml文件的路径X
     * @param node     Xml文件中根结点的名称
     * @return 根结点集合
     * @author com.lin, 2020-02-21
     */
    public static NodeList getNodeList(String filepath, String node) {
        Document document;
        try {
            document = getDocument(filepath);
            //根据标签名获取所有根结点的集合
            return document.getElementsByTagName(node);
        } catch (ParserConfigurationException | SAXException | IOException e) {
            log.error(e.getMessage());
        }
        return null;

    }

    /**
     * 根据Xml获取Document对象
     *
     * @return Document对象
     * @throws ParserConfigurationException Xml异常
     * @throws SAXException                 解析异常
     * @throws IOException                  文件读取异常
     * @author com.lin, 2020-02-20
     */
    private static Document getDocument(String filepath) throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
        File file = FileReadUtil.readToFile(filepath);
        assert file != null;
        return documentBuilder.parse(file);
    }


}
